home *** CD-ROM | disk | FTP | other *** search
- /* Directory hotlist -- for the Midnight Commander
- Copyright (C) 1994 Radek Doulik
- Copyright (C) 1995 Janne Kukonlehto
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include <config.h>
- #ifdef HAVE_UNISTD_H
- # include <unistd.h>
- #endif
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h> /* For malloc() */
- #include <sys/types.h>
- #include <sys/param.h>
- #include <sys/stat.h>
- #include <grp.h>
- #include <pwd.h>
- #include "tty.h"
- #include "mad.h"
- #include "util.h" /* Needed for the externs */
- #include "win.h"
- #include "color.h"
- #include "dlg.h"
- #include "widget.h"
- #include "dialog.h" /* For do_refresh() */
- #include "setup.h" /* For profile_bname */
- #include "profile.h" /* Load/save directories hotlist */
-
- #include "../vfs/vfs.h"
- /* Needed for the extern declarations of integer parameters */
- #include "dir.h"
- #include "panel.h" /* Needed for the externs */
- #include "file.h"
- #include "main.h"
- #include "global.h"
- #include "hotlist.h"
-
- #define UX 5
- #define UY 2
-
- #define BX 5
- #define BY 18
-
- #define BUTTONS 4
- #define LABELS 3
- #define B_ADD B_USER
- #define B_REMOVE B_USER + 1
-
- static WListbox *l_hotlist;
-
- static Dlg_head *hotlist_dlg;
-
- static WLabel *pname;
-
- static char *hotlist_section = "Hotlist";
-
- struct {
- int ret_cmd, y, x;
- char *text;
- int hkey, hpos;
- } hotlist_but[BUTTONS] = {
- { B_CANCEL, 0, 53, "[ Cancel ]", 'c', 2, },
- { B_ADD, 0, 25, "[ Add new ]", 'a', 2, },
- { B_REMOVE, 0, 13, "[ Remove ]", 'r', 2, },
- { B_ENTER, 0, 0, "[[ Chdir ]]", 'd', 5, },
- };
-
- struct {
- int y, x;
- char *text;
- } hotlist_text [LABELS] = {
- { UY, UX + 1, " Directory label " },
- { UY+12, UX+1, " Directory path "},
- { UY+13, UX+2, "" },
- };
-
- /* Directory hotlist */
- static struct hotlist{
- char *directory;
- char *label;
- struct hotlist *next;
- } *hotlist = NULL;
-
- #ifndef HAVE_X
- static void hotlist_refresh (void)
- {
- attrset (REVERSE_COLOR);
- dlg_erase (hotlist_dlg);
-
- draw_box (hotlist_dlg, 1, 2, 20, 70);
- draw_box (hotlist_dlg, UY, UX, 12, 63);
- draw_box (hotlist_dlg, UY + 12, UX, 3, 63);
- }
- #endif
-
- /* If current->data is 0, then we are dealing with a VFS pathname */
- static INLINE void update_path_name ()
- {
- char *text;
-
- if (!l_hotlist->current)
- return;
-
- if (l_hotlist->current->data != 0)
- text = ((struct hotlist *)l_hotlist->current->data)->directory;
- else {
- text = l_hotlist->current->text;
- }
- label_set_text (pname, name_trunc (text, 59));
- }
-
- static int hotlist_callback (Dlg_head * h, int Par, int Msg)
- {
- switch (Msg) {
- #ifndef HAVE_X
- case DLG_DRAW:
- hotlist_refresh ();
- break;
- #endif
-
- case DLG_POST_KEY:
- /* fall */
- case DLG_INIT:
- attrset (MENU_ENTRY_COLOR);
- update_path_name ();
- break;
- }
- return 0;
- }
-
- static int l_call (void *data)
- {
- return 1;
- }
-
- static void add_name_to_list (char *path)
- {
- listbox_add_item (l_hotlist, 0, 0, path, 0);
- }
-
- static void init_hotlist (int is_vfs_list)
- {
- int i;
- struct hotlist *current = hotlist;
-
- do_refresh ();
-
- hotlist_dlg = create_dlg (0, 0, 22, 74, dialog_colors,
- hotlist_callback, "[Hotlist]",
- is_vfs_list ? "vfshot":"hotlist",
- DLG_CENTER);
- x_set_dialog_title (hotlist_dlg,
- is_vfs_list ? "Active VFS directories":"Directory hotlist");
-
- #define XTRACT(i) BY+hotlist_but[i].y, BX+hotlist_but[i].x, hotlist_but[i].ret_cmd, hotlist_but[i].text, hotlist_but[i].hkey, hotlist_but[i].hpos, 0, 0
-
- for (i = 0; i < BUTTONS; i++){
- if (is_vfs_list && (i == 1 || i == 2))
- continue;
- add_widgetl (hotlist_dlg, button_new (XTRACT (i)), (i == BUTTONS - 1) ?
- XV_WLAY_CENTERROW : XV_WLAY_RIGHTOF);
- }
-
- /* We add the labels. We are interested in the last one,
- * that one will hold the path name label
- */
- for (i = 0; i < LABELS; i++){
- pname = label_new (hotlist_text [i].y,
- hotlist_text [i].x, hotlist_text [i].text);
- add_widget (hotlist_dlg, pname);
- }
- /* get new listbox */
- l_hotlist = listbox_new (UY + 1, UX + 1, 61, 10, 0, l_call);
-
- /* Fill the hotlist with the active VFS or the hotlist */
- if (is_vfs_list){
- listbox_add_item (l_hotlist, 0, 0, home_dir, 0);
- vfs_fill_names (add_name_to_list);
- } else
- while (current){
- listbox_add_item (l_hotlist, 0, 0, current->label, current);
- current = current->next;
- }
-
- add_widgetl (hotlist_dlg, l_hotlist, XV_WLAY_EXTENDWIDTH);
- /* add listbox to the dialogs */
- }
-
- static void hotlist_done (void)
- {
- destroy_dlg (hotlist_dlg);
- if (0)
- update_panels (UP_OPTIMIZE, UP_KEEPSEL, UP_KEEPSEL);
- repaint_screen ();
- }
-
- static void add2hotlist (char *label, char *directory)
- {
- struct hotlist *current, *old;
-
- old = NULL;
- current = hotlist;
- while (current && strcmp (current->label, label) <= 0){
- old = current;
- current = current->next;
- }
-
- if (old == NULL){
- hotlist = malloc (sizeof (struct hotlist));
- hotlist->label = label;
- hotlist->directory = directory;
- hotlist->next = current;
- } else {
- struct hotlist *new;
- new = malloc (sizeof (struct hotlist));
- new->label = label;
- new->directory = directory;
- old->next = new;
- new->next = current;
- }
- }
-
- void add2hotlist_cmd (void)
- {
- char *prompt, *label;
-
- prompt = malloc (strlen (cpanel->cwd) + 20);
- sprintf (prompt, "Label for \"%s\":", cpanel->cwd);
- label = input_dialog (" Add to hotlist ", prompt, "");
- free (prompt);
- if (!label || !*label)
- return;
-
- add2hotlist (label, strdup (cpanel->cwd));
- }
-
- static void remove_from_hotlist (struct hotlist *entry)
- {
- if (entry == hotlist){
- hotlist = hotlist->next;
- } else {
- struct hotlist *current = hotlist;
- while (current && current->next != entry)
- current = current->next;
- if (current){
- current->next = entry->next;
- }
- }
-
- /* FIXME: Commented out because freeing seems to cause corruption
- after some add and remove operations */
- /*free (entry->label);
- free (entry->directory);
- free (entry);*/
- }
-
- char *hotlist_cmd (int vfs_or_hotlist)
- {
- char *target = NULL;
-
- init_hotlist (vfs_or_hotlist);
-
- /* display file info */
- attrset (SELECTED_COLOR);
-
- run_dlg (hotlist_dlg);
-
- switch (hotlist_dlg->ret_value) {
- case B_CANCEL:
- break;
-
- case B_ADD:
- add2hotlist_cmd ();
- break;
-
- case B_REMOVE:
- remove_from_hotlist (l_hotlist->current->data);
- break;
-
- case B_ENTER:
- if (l_hotlist->current->data)
- target = ((struct hotlist*) l_hotlist->current->data) -> directory;
- else
- target = strdup (l_hotlist->current->text);
- break;
- }
-
- hotlist_done ();
- return target;
- }
-
- void load_hotlist (void)
- {
- void *profile_keys;
- char *key, *value;
-
- profile_keys = profile_init_iterator (hotlist_section, profile_name);
-
- if (!profile_keys){
- add2hotlist (strdup ("Home directory"), strdup (home_dir));
- add2hotlist (strdup ("Root directory"), strdup (PATH_SEP_STR));
- return;
- }
-
- while (profile_keys){
- profile_keys = profile_iterator_next (profile_keys, &key, &value);
- add2hotlist (strdup (value), strdup (key));
- }
- }
-
- void save_hotlist (void)
- {
- struct hotlist *current = hotlist;
-
- profile_clean_section (hotlist_section, profile_name);
- for (;current; current = current->next){
- WritePrivateProfileString (hotlist_section,
- current->directory,
- current->label,
- profile_name);
- }
- /* So that maybe later setup is not saved if not asked to */
- sync_profiles ();
- }
-
- void done_hotlist (void)
- {
- struct hotlist *current = hotlist;
- struct hotlist *next;
-
- for (; current; current = next){
- next = current->next;
- free (current->label);
- free (current->directory);
- free (current);
- }
- }
-